package org.rsbot.gui;

import java.awt.event.ActionListener;
import java.io.File;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;

import javax.swing.ImageIcon;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JSeparator;

import org.rsbot.bot.Bot;
import org.rsbot.event.impl.DrawInventory;
import org.rsbot.event.impl.DrawItems;
import org.rsbot.event.impl.DrawModel;
import org.rsbot.event.impl.DrawMouse;
import org.rsbot.event.impl.DrawNPCs;
import org.rsbot.event.impl.DrawObjects;
import org.rsbot.event.impl.DrawPlayers;
import org.rsbot.event.impl.MessageLogger;
import org.rsbot.event.impl.TAnimation;
import org.rsbot.event.impl.TCamera;
import org.rsbot.event.impl.TFPS;
import org.rsbot.event.impl.TFloorHeight;
import org.rsbot.event.impl.TLoginIndex;
import org.rsbot.event.impl.TMenu;
import org.rsbot.event.impl.TMenuActions;
import org.rsbot.event.impl.TMousePosition;
import org.rsbot.event.impl.TOrientation;
import org.rsbot.event.impl.TPlayerPosition;
import org.rsbot.event.impl.TTab;
import org.rsbot.event.impl.TUserInputAllowed;
import org.rsbot.event.listeners.PaintListener;
import org.rsbot.event.listeners.TextPaintListener;
import org.rsbot.util.GlobalConfiguration;

public class BotMenuBar extends JMenuBar {

    private static final long serialVersionUID = 971579975301998332L;
    public static final Map<String, Class<?>> DEBUG_MAP = new LinkedHashMap<String, Class<?>>();
    public static final String[] TITLES;
    public static final String[][] ELEMENTS;
    public static final ImageIcon bug;
    public static final ImageIcon account;
    public static final ImageIcon start;
    public static final ImageIcon stop;
    public static final ImageIcon pauseico;
    public static final ImageIcon input;
    public static final ImageIcon noinput;
    public static final ImageIcon cpu;
    public static final ImageIcon exit;

    static {
    	System.out.println(GlobalConfiguration.RUNNING_FROM_JAR);
        ImageIcon icon = null;
        try {
            icon = new ImageIcon(GlobalConfiguration.RUNNING_FROM_JAR
                    ? BotMenuBar.class.getResource(GlobalConfiguration.Paths.Resources.BUG)
                    : new File(GlobalConfiguration.Paths.BUG).toURI().toURL());
        } catch (final MalformedURLException ignored) {
        }
        bug = icon;
        try {
            icon = new ImageIcon(GlobalConfiguration.RUNNING_FROM_JAR
                    ? BotMenuBar.class.getResource(GlobalConfiguration.Paths.Resources.ACCOUNT)
                    : new File(GlobalConfiguration.Paths.ACCOUNT).toURI().toURL());
        } catch (final MalformedURLException ignored) {
        }
        account = icon;
        try {
            icon = new ImageIcon(GlobalConfiguration.RUNNING_FROM_JAR
                    ? BotMenuBar.class.getResource(GlobalConfiguration.Paths.Resources.ICON_PLAY)
                    : new File(GlobalConfiguration.Paths.ICON_PLAY).toURI().toURL());
        } catch (final MalformedURLException ignored) {
        }
        start = icon;
        try {
            icon = new ImageIcon(GlobalConfiguration.RUNNING_FROM_JAR
                    ? BotMenuBar.class.getResource(GlobalConfiguration.Paths.Resources.STOP_DO)
                    : new File(GlobalConfiguration.Paths.STOP_DO).toURI().toURL());
        } catch (final MalformedURLException ignored) {
        }
        stop = icon;
        try {
            icon = new ImageIcon(GlobalConfiguration.RUNNING_FROM_JAR
                    ? BotMenuBar.class.getResource(GlobalConfiguration.Paths.Resources.ICON_PAUSE)
                    : new File(GlobalConfiguration.Paths.ICON_PAUSE).toURI().toURL());
        } catch (final MalformedURLException ignored) {
        }
        pauseico = icon;
        try {
            icon = new ImageIcon(GlobalConfiguration.RUNNING_FROM_JAR
                    ? BotMenuBar.class.getResource(GlobalConfiguration.Paths.Resources.ICON_TICK)
                    : new File(GlobalConfiguration.Paths.ICON_TICK).toURI().toURL());
        } catch (final MalformedURLException ignored) {
        }
        input = icon;
        try {
            icon = new ImageIcon(GlobalConfiguration.RUNNING_FROM_JAR
                    ? BotMenuBar.class.getResource(GlobalConfiguration.Paths.Resources.ICON_DELETE)
                    : new File(GlobalConfiguration.Paths.ICON_DELETE).toURI().toURL());
        } catch (final MalformedURLException ignored) {
        }
        noinput = icon;
        try {
            icon = new ImageIcon(GlobalConfiguration.RUNNING_FROM_JAR
                    ? BotMenuBar.class.getResource(GlobalConfiguration.Paths.Resources.CPU)
                    : new File(GlobalConfiguration.Paths.CPU).toURI().toURL());
        } catch (final MalformedURLException ignored) {
        }
        cpu = icon;
        try {
            icon = new ImageIcon(GlobalConfiguration.RUNNING_FROM_JAR
                    ? BotMenuBar.class.getResource(GlobalConfiguration.Paths.Resources.GUI_CLOSE)
                    : new File(GlobalConfiguration.Paths.GUI_CLOSE).toURI().toURL());
        } catch (final MalformedURLException ignored) {
        }
        exit = icon;


        // Text
        DEBUG_MAP.put("Game State", TLoginIndex.class);
        DEBUG_MAP.put("Current Tab", TTab.class);
        DEBUG_MAP.put("Camera", TCamera.class);
        DEBUG_MAP.put("Animation", TAnimation.class);
        DEBUG_MAP.put("Floor Height", TFloorHeight.class);
        DEBUG_MAP.put("Player Position", TPlayerPosition.class);
        DEBUG_MAP.put("Orientation", TOrientation.class);
        DEBUG_MAP.put("Mouse Position", TMousePosition.class);
        DEBUG_MAP.put("User Input Allowed", TUserInputAllowed.class);
        DEBUG_MAP.put("Menu Actions", TMenuActions.class);
        DEBUG_MAP.put("Menu", TMenu.class);
        DEBUG_MAP.put("FPS", TFPS.class);

        // Paint
        DEBUG_MAP.put("Players", DrawPlayers.class);
        DEBUG_MAP.put("NPCs", DrawNPCs.class);
        DEBUG_MAP.put("Objects", DrawObjects.class);
        DEBUG_MAP.put("Models", DrawModel.class);
        DEBUG_MAP.put("Mouse", DrawMouse.class);
        DEBUG_MAP.put("Inventory", DrawInventory.class);
        DEBUG_MAP.put("Ground Items", DrawItems.class);
        //DEBUG_MAP.put("Calc Test", DrawBoundaries.class);
        //DEBUG_MAP.put("Settings", DrawSettings.class);

        // Other
        DEBUG_MAP.put("Log Messages", MessageLogger.class);

        TITLES = new String[]{"Client", "Screen Shots", "Anti-Bans", "Hide", "Debug", "Skins", "Help"};
        ELEMENTS = new String[][]{
                    //{"New Bot", "Close Bot", "-", "Run Script", "Stop Script", "Pause Script", "-", "Save Screenshot", "-", "Exit"},
                    {"New Bot", "Accounts", "-", "Run Script", "Stop Script", "Pause Script", "-", "ToggleF Force Input", "ToggleF Less CPU", "-", "Exit"},
                    {"Save ScreenShot", "Save ScreenShot (UnCen)"},
                    {"ToggleF Disable Anti-Randoms", "ToggleF Disable Anti-Bans", "ToggleF Disable Auto Login", "ToggleF Disable Break Handler", "ToggleF Disable First Time Death"},
                    constructHides(),
                    constructDebugs(),
                    constructThemes(),
                    {"Troubleshooting", "Site", "Wiki", "Facebook", "Twitter", "Project", "The Bot", "The Makers"}};
    }

    private static String[] constructHides() {
        final List<String> hideItems = new ArrayList<String>();
        hideItems.add("Hide Toolbar");
        hideItems.add("Hide Option Buttons");
        hideItems.add("Hide Option Console");
        //hideItems.add("Hide Tray Icon");
        for (final ListIterator<String> it = hideItems.listIterator(); it.hasNext();) {
            final String s = it.next();
            if (!s.equals("-")) {
                it.set("ToggleF " + s);
            }
        }
        return hideItems.toArray(new String[hideItems.size()]);
    }

    private static String[] constructDebugs() {
        final List<String> debugItems = new ArrayList<String>();
        debugItems.add("All Debugging");
        debugItems.add("-");
        for (final String key : DEBUG_MAP.keySet()) {
            final Class<?> el = DEBUG_MAP.get(key);
            if (PaintListener.class.isAssignableFrom(el)) {
                debugItems.add(key);
            }
        }
        debugItems.add("-");
        for (final String key : DEBUG_MAP.keySet()) {
            final Class<?> el = DEBUG_MAP.get(key);
            if (TextPaintListener.class.isAssignableFrom(el)) {
                debugItems.add(key);
            }
        }
        debugItems.add("-");
        for (final String key : DEBUG_MAP.keySet()) {
            final Class<?> el = DEBUG_MAP.get(key);
            if (!(TextPaintListener.class.isAssignableFrom(el)) && !(PaintListener.class.isAssignableFrom(el))) {
                debugItems.add(key);
            }
        }
        for (final ListIterator<String> it = debugItems.listIterator(); it.hasNext();) {
            final String s = it.next();
            if (!s.equals("-")) {
                it.set("ToggleF " + s);
            }
        }
        return debugItems.toArray(new String[debugItems.size()]);
    }
    
    private static String[] constructThemes() {
        final String[] themeSet = new String[BotGUI.themes.size()];
        int themeIndex = 0;
        for (final String key : BotGUI.themes.keySet()) {
            themeSet[themeIndex] = "Toggle" + (key.equals("System") ? "F" : "F") + " " + key;
            themeIndex++;
        }
        return themeSet;
    }

    public static Map<String, JCheckBoxMenuItem> eventCheckMap = new HashMap<String, JCheckBoxMenuItem>();
    public static Map<String, JCheckBoxMenuItem> commandCheckMap = new HashMap<String, JCheckBoxMenuItem>();
    public static Map<String, JMenuItem> commandMenuItem = new HashMap<String, JMenuItem>();
    private final ActionListener listener;

    public BotMenuBar(final ActionListener listener) {
        this.listener = listener;
        for (int i = 0; i < TITLES.length; i++) {
            final String title = TITLES[i];
            final String[] elems = ELEMENTS[i];
            add(constructMenu(title, elems));
        }
    }

    public void setOverrideInput(final boolean force) {
        commandCheckMap.get("Force Input").setSelected(force);
        commandCheckMap.get("Force Input").setIcon(input);
    }

    public void setPauseScript(final boolean pause) {
        commandMenuItem.get("Pause Script").setText(pause ? "Resume Script" : "Pause Script");
        commandMenuItem.get("Pause Script").setIcon(pause ? start : pauseico);
    }

    public void setBot(final Bot bot) {
        commandMenuItem.get("Accounts").setIcon(account);
        commandMenuItem.get("Run Script").setIcon(start);
        commandMenuItem.get("Stop Script").setIcon(stop);
        commandMenuItem.get("Pause Script").setIcon(pauseico);
        commandCheckMap.get("Force Input").setIcon(noinput);
        commandCheckMap.get("Less CPU").setIcon(cpu);
        commandMenuItem.get("Exit").setIcon(exit);
        //commandMenuItem.get("Save ScreenShot").setIcon(stop);
        //commandCheckMap.get("All Debugging").setIcon(stop);
        //eventCheckMap.get("Game State").setIcon(bug);
        //eventCheckMap.get("Current Tab").setIcon(bug);
        //eventCheckMap.get("Camera").setIcon(bug);
        //eventCheckMap.get("Animation").setIcon(bug);
        //eventCheckMap.get("Floor Height").setIcon(bug);
        //eventCheckMap.get("Player Position").setIcon(bug);
        //eventCheckMap.get("Mouse Position").setIcon(bug);
        //eventCheckMap.get("User Input Allowed").setIcon(bug);
        //eventCheckMap.get("Menu Actions").setIcon(bug);
        //eventCheckMap.get("Menu").setIcon(bug);
        //eventCheckMap.get("FPS").setIcon(bug);
        //eventCheckMap.get("Players").setIcon(bug);
        //eventCheckMap.get("NPCs").setIcon(bug);
        //eventCheckMap.get("Objects").setIcon(bug);
        //eventCheckMap.get("Models").setIcon(bug);
        //eventCheckMap.get("Mouse").setIcon(bug);
        //eventCheckMap.get("Inventory").setIcon(bug);
        //eventCheckMap.get("Ground Items").setIcon(bug);
        //eventCheckMap.get("Calc Test").setIcon(bug);
        //eventCheckMap.get("Settings").setIcon(bug);
        //eventCheckMap.get("Log Messages").setIcon(bug);
        if (bot == null) {
            //commandMenuItem.get("Close Bot").setEnabled(false);
            commandMenuItem.get("Run Script").setEnabled(false);
            commandMenuItem.get("Stop Script").setEnabled(false);
            commandMenuItem.get("Pause Script").setEnabled(false);
            //commandMenuItem.get("Save ScreenShot").setEnabled(false);
            for (final JCheckBoxMenuItem item : eventCheckMap.values()) {
                item.setSelected(false);
                item.setEnabled(false);
            }
            disable("All Debugging", "Force Input", "Less CPU",
                    "Disable Anti-Randoms", "Disable Anti-Bans", "Disable Auto Login", "Disable Break Handler", "Disable First Time Death");
        } else {
            //commandMenuItem.get("Close Bot").setEnabled(true);
            commandMenuItem.get("Run Script").setEnabled(true);
            commandMenuItem.get("Stop Script").setEnabled(true);
            commandMenuItem.get("Pause Script").setEnabled(true);
            commandMenuItem.get("Save ScreenShot").setEnabled(true);
            int selections = 0;
            for (final Map.Entry<String, JCheckBoxMenuItem> entry : eventCheckMap.entrySet()) {
                entry.getValue().setEnabled(true);
                final boolean selected = bot.hasListener(DEBUG_MAP.get(entry.getKey()));
                entry.getValue().setSelected(selected);
                if (selected) {
                    ++selections;
                }
            }
            enable("All Debugging", selections == eventCheckMap.size());
            enable("Force Input", bot.overrideInput);
            enable("Less CPU", bot.disableRendering);
            enable("Disable Anti-Randoms", bot.disableRandoms);
            enable("Disable Anti-Bans", bot.disableRandoms);
            enable("Disable Auto Login", bot.disableAutoLogin);
            enable("Disable Break Handler", bot.disableBreakHandler);
            enable("Disable First Time Death", bot.disableFirstTimeDeath);
        }
    }

    public JCheckBoxMenuItem getCheckBox(final String key) {
        return commandCheckMap.get(key);
    }

    public JCheckBoxMenuItem getCheckBoxEvent(final String key) {
        return eventCheckMap.get(key);
    }

    private void disable(final String... items) {
        for (final String item : items) {
            commandCheckMap.get(item).setSelected(false);
            commandCheckMap.get(item).setEnabled(false);
        }
    }

    private void enable(final String item, final boolean selected) {
        commandCheckMap.get(item).setSelected(selected);
        commandCheckMap.get(item).setEnabled(true);
    }

    private JMenu constructMenu(final String title, final String[] elems) {
        final JMenu menu = new JMenu(title);
        for (String e : elems) {
            if (e.equals("-")) {
                menu.add(new JSeparator());
            } else {
                JMenuItem jmi;
                if (e.startsWith("Toggle")) {
                    e = e.substring("Toggle".length());
                    final char state = e.charAt(0);
                    e = e.substring(2);
                    jmi = new JCheckBoxMenuItem(e);
                    if ((state == 't') || (state == 'T')) {
                        jmi.setSelected(true);
                    }
                    if (DEBUG_MAP.containsKey(e)) {
                        eventCheckMap.put(e, (JCheckBoxMenuItem) jmi);
                    }
                    commandCheckMap.put(e, (JCheckBoxMenuItem) jmi);
                } else {
                    jmi = new JMenuItem(e);
                    commandMenuItem.put(e, jmi);
                }
                jmi.addActionListener(listener);
                jmi.setActionCommand(title + "." + e);
                menu.add(jmi);
            }
        }
        return menu;
    }
}
